home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
TURB_VIS
/
RESDMP11
/
RESDUMP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-07-26
|
25KB
|
710 lines
{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,R+,S+,T-,V+,X+,Y-}
{$M 16384,0,655360}
{ W. Gross, April 1992,
Vs. 1.1, last change: 26-JUL-93}
{handles only objects
TMenuBar, TStatusLine, TStringList and
TDialog with these imbedded controls:
TView, TButton, TRadioButton, TCheckBoxes,THistory,
TInputLine, TParamText, TListViewer, TStaticText.
Program cannot correctly recover the heap, if unregistered
objects are encountered inside TDialog objects.
}
program ResDump;
uses Crt,Dos,Objects,Drivers,Views,Menus,Dialogs,Memory,
GADGETS, MSGBOX, STDDLG, RESDUTIL, DRESFU, App;
const
cmAboutDialog = 101;
cmDumpDialog = 111;
cmNewOutFileD = 121;
cmDoubleClick = 130;
cmDAll = 131;
cmDDialog = 132;
cmDMenubar = 133;
cmDStatusline = 134;
cmDStringList = 135;
cmDFI = 136;
hcResList = 1138;
hcOutFile = 1121;
hcResFile = 1111;
{change these constants as convenient +++}
cmStartScrnSaver = 200; {+++}
cmStopScrnSaver = 201; {+++}
{your favorite text here}
ScrnSaverText : String = 'RESDUMP lurking ...' ; {+++}
GracePeriod : longint = 5000; {ask DOS time after graceperiod} {+++}
{all time values in centiseconds +++}
{Invoke screen saver after program is idle for ScrnSaverDelay centisecs}
ScrnSaverDelay : longint = 6000; {+++}
ScrnSaverInt : longint = 500; {+++}
type
PFileStatusBox = ^TFileStatusBox;
TFileStatusbox = object (TView)
procedure draw ; virtual;
END;
PWaitDialog = ^TWaitDialog;
TWaitDialog = object (TDialog)
function getpalette : PPalette; virtual;
END;
TMyApp = object(TApplication)
ScrnSaverKickTime, {+++}
ScrnSaverLastTime : longint; {centiseconds} {+++}
ScrnSaverMode : boolean; {+++}
GraceCounter : word; {ask DOS time only if > GracePeriod} {+++}
OutFileName,ResFileName : PathStr;
OutFileOpen, ResFileOpen : boolean;
Heap : PHeapView;
Clock : PClockView;
FBox : PFileStatusBox;
constructor Init;
destructor Done; virtual;
procedure InitMenuBar; virtual;
procedure GetEvent(var Event: TEvent); virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitStatusLine; virtual;
procedure Idle; virtual;
function GetPalette: PPalette;virtual;
procedure AboutDialog;
procedure DumpDialog;
procedure OutFileDialog;
end;
PClickListBox = ^TClickListBox;
TClickListBox = object (TListBox)
procedure HandleEvent (Var Event : TEvent ); virtual;
END;
PResDialog = ^TResDialog;
TResDialog = object (TDialog)
ResFileName : PathStr;
RLB : PClickListBox;
Collection : PStringCollection;
PROCEDURE RestInit ( FName : PathStr );
procedure HandleEvent ( VAR Event : TEvent ); virtual;
procedure InitCollection;
destructor done;virtual;
END;
PMyStatusLine = ^TMyStatusLine;
TMyStatusLine = object (TStatusLine)
FUNCTION Hint (AHelpCtx : Word ) : String ; VIRTUAL;
END;
VAR
MyApp : TMyApp;
outfile : text;
BufStream,MyAppResStream : PBufStream;
MyAppResFile, ResFile : TResourceFile;
WaitBox : PDialog;
EXEName,BRSName : PathStr;
Ed : DirStr; En : NameStr; Ee : ExtStr;
HCTEXT_SL : PStringList;
FUNCTION Time:longint; {+++ we need this function +++}
{Return real day time in centiseconds. One might get in trouble with
measurements spanning midnight. Smallest reliable interval: 55 msec}
VAR Hour,Minute,Second,Sec100: WORD; {+++}
BEGIN {+++}
GetTime(Hour,Minute,Second,Sec100); {+++}
Time:=longint(Sec100)+100*(longint(Second) {+++}
+60*(longint(Minute)+60*longint(hour))); {+++}
END; {+++}
{ TMyStatusLine }
FUNCTION TMyStatusLine.Hint(AHelpCtx : Word ) : String ;
VAR s : String[80];
BEGIN
s := '';
IF HCTEXT_SL<>NIL THEN
s := HCTEXT_SL^.Get(AHelpCtx);
IF s='' THEN
BEGIN str ( AHelpCtx, s ); s := 'hcxxxx='+s; END; {!change!}
Hint := s;
END; {FUNC TMyStatusLine.Hint}
{ TResDialog }
PROCEDURE TResDialog.InitCollection;
{only TDialog, TMenuBar, TStringList objects}
VAR i : integer;
s40 : String[40];
Key,Typ : String;
TOD,TOM,TOS,TOSL : Pointer;
MyObj : PObject;
heapav : longint;
BEGIN
TOM := TypeOf(TMenuBar);
TOD := TypeOf(TDialog);
TOS := TypeOf(TStringList);
TOSL:= TypeOf(TStatusLine);
IF Collection<>NIL THEN Dispose (Collection,Done);
BufStream := New (PBufStream, Init(ResFileName, stOpenRead, 1024));
ResFile.Init(BufStream);
Collection := New(PStringCollection, Init(ResFile.Count,1));
FOR i := 0 TO ResFile.Count-1 DO
BEGIN
heapav := memavail;
Key := ResFile.KeyAt(i);
MyObj := ResFile.Get(Key);
heapav := memavail;
Typ := '<Derived> ';
IF (ResFile.Stream^.status<>stOk) {unregistered object encountered}
THEN ResFile.Stream^.Reset; {resume stream operation}
{stream error may also occur if an unregistered object exists
inside a TDialog object, in this case the heap is not correctly
cleared}
IF MyObj<>NIL THEN
BEGIN
Typ := '<Other> ';
IF TypeOf(MyObj^)=TOM THEN Typ := '[TMenubar] ';
IF TypeOf(MyObj^)=TOD THEN Typ := '[TDialog] ';
IF TypeOf(MyObj^)=TOSL THEN Typ := '[TStatusLine] ';
IF TypeOf(MyObj^)=TOS THEN Typ := '[TStringList] ';
Dispose(MyObj,Done);
END; {IF ResFile.Stream^.status .... THEN ... ELSE ...}
heapav := memavail;
s40 := Typ+Key;
Collection^.Insert(NewStr(s40));
END;
END;
DESTRUCTOR TResDialog.Done;
BEGIN
Dispose(Collection,Done);
TDialog.Done;
ResFile.Done;
END;
procedure TClickListBox.HandleEvent ( Var Event : TEvent );
{intercept mouse double click and return cmDoubleClick}
BEGIN
IF (Event.What=evMouseDown) AND (Event.Double)
THEN
BEGIN
Event.What := evCommand;
Event.Command := cmDoubleClick;
PutEvent(Event);
ClearEvent(Event);
END
ELSE TListBox.HandleEvent(Event);
END;
procedure TResDialog.Restinit ( FName : PathStr);
VAR R : TRect;
View : PView;
BEGIN
ResFileName := FName;
Collection := NIL;
R.Assign(0,0,0,0);
RLB := New(PClickListBox,Init(R,1,nil));
View :=ReplaceControl( PDialog(@Self), RLB, hcResList,
TypeOf(TListViewer));
IF View=NIL THEN
BEGIN donevideo; writeln ('Replace error' ); halt; end;
InitCollection;
RLB^.NewList(Collection);
writeln ( outfile );
writeln ( outfile, 'Dump of '+ResFileName+' on ', FDate);
writeln ( outfile,
'---------------------------------------------------------');
writeln ( outfile ); writeln ( outfile );
END; {PROC TResDialog.RestInit}
procedure TResDialog.HandleEvent ( VAR Event : TEvent );
var s : PString; todo : word;
ItemKey : String;
StreamErrorOccured : boolean;
BEGIN
TDialog.HandleEvent(Event); {catches cmCancel}
StreamErrorOccured := false;
IF (Event.What=evCommand) THEN
BEGIN
IF Event.Command IN
[cmDAll,cmDDialog,cmDMenubar,cmDStringList,
cmDStatusLine,cmDFI,cmDoubleClick]
THEN WaitBox^.Show;
CASE Event.Command OF
cmDAll :
BEGIN
DumpIt ( 'A', '', outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
cmDDialog :
BEGIN
DumpIt ( 'D', '', outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
cmDMenubar :
BEGIN
DumpIt ( 'M', '', outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
cmDStatusLine:
BEGIN
DumpIt ( 'L', '', outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
cmDStringList :
BEGIN
DumpIt ( 'S', '', outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
cmDFI, cmDoubleClick :
BEGIN
s := PString(RLB^.List^.At(RLB^.focused));
ItemKey := copy ( s^, 17,23);
DumpIt ( 'F', ItemKey, outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
ELSE
END; {CASE Event.Command}
IF Event.Command IN
[cmDAll,cmDDialog,cmDMenubar,cmDStringList,
cmDStatusLine,cmDFI,cmDoubleClick]
THEN WaitBox^.Hide;
END;
IF (Event.What=evKeyDown) AND (Event.KeyCode=kbEnter) THEN
BEGIN
s := PString(RLB^.List^.At(RLB^.focused));
ItemKey := copy ( s^, 17,23);
DumpIt ( 'F', ItemKey, outfile, ResFile, StreamErrorOccured );
ClearEvent(Event);
END;
IF StreamErrorOccured THEN
messagebox(
'Stream error in resource file !'#13+
'Check output file for more info.'#13'Warning: Garbage on heap.',
nil, mfError+mfOkButton);
END; {PROC TResDialog.HandleEvent}
{--------------------------------------------------}
{ TFileStatusBox }
PROCEDURE TFileStatusBox.Draw;
{nonlocal: MyApp.OutFileName,ResFileName}
VAR Params : ARRAY[0..1] OF Pointer;
name1,name2 : String[15];
Result : String;
i,l : integer;
BEGIN
Name1 := FBase(MyApp.ResFileName); l := length(Name1);
FOR i := 1 TO 15-l DO Name1 := ' '+Name1;
Params[0] := @Name1;
Name2 := FBase(MyApp.OutFileName)+' ';
Params[1]:= @Name2;
FormatStr ( Result, '%15s --> %15s', Params);
writestr(0,0,Result,7);
END;
{ Waitbox }
FUNCTION TWaitDialog.GetPalette : PPalette;
{static text blinks, frame }
CONST s : String[length(CGrayDialog)] = CGrayDialog;
VAR i : integer;
BEGIN
i := length(Application^.GetPalette^);
s[1] := chr(i-1); s[2] := chr(i-1); s[6] := chr(i);
GetPalette := PPalette(@s);
END; {FUNC TWaitBox.GetPalette}
{ TMyApp}
constructor TMyApp.Init;
VAR InitEvent : TEvent;
R, R1 : TRect;
begin {Init}
MyAppResStream := New(PBufStream, Init(BRSName, stOpenRead, 4096));
MyAppResFile.Init(MyAppResStream);
HCTEXT_SL := PStringList(MyAppResFile.Get('RESDUMP_HT'));
TApplication.Init;
ScrnSaverKickTime := 0; {+++}
ScrnSaverLastTime := 0; {+++}
ScrnSaverMode := false; {+++}
GraceCounter :=0; {+++}
OutFileName := 'RESDUMP.OUT'; {default output name}
ResFileName := '';
OutFileOpen := false; ResFileOpen := false;
GetExtent(R);
R.A.X := R.B.X - 49; R.B.X := R.B.X - 40;
R.B.Y := R.A.Y + 1;
Clock := New(PClockView, Init(R));
Insert(Clock);
GetExtent(R);
Dec(R.B.X);
R.A.X := R.B.X - 9; R.A.Y := R.B.Y - 1;
Heap := New(PHeapView, Init(R));
Insert(Heap);
GetExtent(R1);
R1.A.X := R1.B.X-35; R1.B.Y := R1.A.Y+1;
FBox := New(PFileStatusBox,Init(R1));
IF ValidView(FBox)<>NIL THEN Insert(FBox);
{insert waitbox in desktop, but do not show now}
WaitBox := nil;
IF LowMemory
THEN OutOfMemory
ELSE
BEGIN
RDialog.VMTLink := Ofs(TypeOf(TWaitDialog)^);
WaitBox := PDialog(MyAppResFile.Get('WAITBOX_DB'));
RDialog.VMTLink := Ofs(TypeOf(TDialog)^);
END;
IF ValidView(WaitBox) <> NIL THEN
BEGIN
WaitBox^.SetState(sfVisible OR sfShadow,false);
Insert(WaitBox); {insert into application}
END;
WITH InitEvent DO
BEGIN What := evCommand; Command := cmNewOutFileD; END;
PutEvent ( InitEvent );
end; {Init}
PROCEDURE TMyApp.InitMenuBar;
BEGIN
MenuBar := PMenuBar(MyAppResFile.Get('RESDUMP_MB'));
IF MenuBar=NIL THEN {no error checking done!}
END;{PROC TMyApp.InitMenuBar}
procedure TMyApp.InitStatusLine;
var R : TRect;
begin {InitStatusLine}
RStatusLine.VMTLink := Ofs(TypeOf(TMyStatusLine)^);
StatusLine := PStatusLine(MyAppResFile.Get('RESDUMP_ST'));
RStatusline.VMTLink := Ofs(TypeOf(TStatusLine)^);
IF Statusline=NIL THEN {no error checking done!}
end; {InitStatusLine}
PROCEDURE TMyApp.Idle;
BEGIN
inherited Idle;
IF ScrnSaverMode {+++}
THEN {+++}
BEGIN {+++}
IF ((Time-ScrnSaverLastTime)>ScrnSaverInt) THEN {+++}
BEGIN {+++}
ClrScr; {+++}
TextColor(Random(14)+1); {+++}
Gotoxy ( Random(80-length(ScrnSaverText)), Random(24)); {+++}
write ( ScrnSaverText ); ScrnSaverLastTime := Time; {+++}
END; {+++}
END {+++}
ELSE {+++}
BEGIN {+++}
Heap^.Update; Clock^.Update; {+++}
END; {+++}
END;{PROC TMyApp.Idle}
destructor TMyApp.Done;
begin {Done}
IF OutFileOpen THEN close ( outfile );
TApplication.Done
end; {Done}
procedure TMyApp.GetEvent ( VAR Event : TEvent );
VAR p : pointer; SEvent : TEvent;
BEGIN
inherited GetEvent(Event);
{Reset counter if event pending but do not kill this event +++}
IF Event.What<>evNothing THEN {+++}
BEGIN {+++}
GraceCounter := 0; ScrnSaverKickTime := 0; {+++}
IF ScrnSaverMode THEN {+++}
BEGIN {+++}
SEvent.What := evcommand; {+++}
SEvent.command := cmStopScrnSaver; {+++}
HandleEvent(SEvent); {+++}
Exit; {+++}
END; {+++}
END; {+++}
IF NOT ScrnSaverMode THEN {+++}
IF GraceCounter < GracePeriod {start calling DOS time after +++}
THEN Inc(GraceCounter) {grace period since it's too +++}
ELSE {time consuming. +++}
BEGIN
IF ScrnSaverKickTime=0 THEN ScrnSaverKickTime := Time; {+++}
IF ((Time-ScrnSaverKickTime)>ScrnSaverDelay) THEN {+++}
BEGIN {+++}
SEvent.What := evcommand; {+++}
SEvent.command := cmStartScrnSaver; {+++}
HandleEvent(SEvent); {+++}
Exit; {+++}
END; {+++}
END; {+++}
END; {PROC TMyApp.GetEvent}
procedure TMyApp.HandleEvent(var Event: TEvent);
begin {HandleEvent}
TApplication.HandleEvent(Event);
if (Event.What = evCommand) then
begin
case Event.Command of
cmAboutDialog :
AboutDialog;
cmDumpDialog :
DumpDialog;
cmNewOutFileD : BEGIN
OutFileDialog;
Event.command := cmDumpDialog; PutEvent(Event);
END;
cmStartScrnSaver : {+++}
BEGIN {+++}
ScrnSaverLastTime := 0; {+++}
ScrnSaverMode := true; {+++}
TextBackGround(Black); {+++}
END; {+++}
cmStopScrnSaver : {+++}
IF ScrnSaverMode THEN {+++}
BEGIN {+++}
ScrnSaverMode := false; {+++}
ScrnSaverKickTime := 0; GraceCounter := 0; {+++}
inherited redraw; {+++}
END; {+++}
else
Exit;
end;
ClearEvent(Event);
end
end; {HandleEvent}
function TMyApp.GetPalette: PPalette;
const
CWaitColor=#$50#$F4;
CNewColor = CAppColor + CWaitColor;
CNewBlackWhite = CAppBlackWhite + CWaitColor;
CNewMonochrome = CAppMonochrome + CWaitColor;
P: array[apColor..apMonochrome] of string[Length(CNewColor)] =
(CNewColor, CNewBlackWhite, CNewMonochrome);
begin
GetPalette := @P[AppPalette];
end;
procedure TMyApp.AboutDialog;
var
Dialog : PDialog;
C : word;
begin {AboutDialog}
Dialog := PDialog(MyAppResFile.Get('ABOUT_DB'));
IF ValidView(Dialog)<>nil THEN
BEGIN
C := DeskTop^.ExecView(Dialog);
Dispose(Dialog,Done);
END;
end; {AboutDialog}
procedure TMyApp.DumpDialog;
var
R : TRect;
Dialog : PResDialog;
D : PFileDialog;
View : PView;
C : word;
ResDir : DirStr; ResName : NameStr; ResExt : ExtStr;
ResFullName : String;
begin {DumpDialog}
D := New (PFileDialog, Init('*.BRS', 'Open Resource File',
'~N~ame',fdOpenButton,100));
D^.HelpCtx := hcResFile;
IF ValidView(D)<>NIL THEN
BEGIN
IF DeskTop^.ExecView(D) <> cmCancel THEN
BEGIN
D^.GetFileName(ResFileName);
FSplit(ResFileName,ResDir,ResName,ResExt);
ResFileName := ResDir+ResName+ResExt;
FBox^.drawview;
{fool Stream mechanism, works for TDialog derivatives}
RDialog.VMTLink := Ofs(TypeOf(TResDialog)^);
Dialog := PResDialog(MyAppResFile.Get('SELECT_DB'));
RDialog.VMTLink := Ofs(TypeOf(TDialog)^);
Dialog^.RestInit(ResFileName);
C := DeskTop^.ExecView(Dialog);
Dispose(Dialog,Done);
ResFileName := '';
FBox^.drawview;
END;
Dispose(D,Done);
END;
end; {PROC DumpDialog}
procedure TMyApp.OutFileDialog;
var
Dialog : PFileDialog;
OutFD : PDialog;
todo, c : word;
Param : Pointer;
FullName : PathStr;
Dir : DirStr; Ext : ExtStr; Name : NameStr;
Again, AppendToOldOutFile : boolean;
begin {OutFileDialog}
Dialog := New (PFileDialog, Init(OutFileName, 'Open Output File',
'~N~ame',fdOpenButton,101));
Dialog^.HelpCtx := hcOutFile;
FullName := '';
Again := true;
IF ValidView(Dialog)=NIL
THEN BEGIN DoneVideo; writeln ('ValidView error.'); halt; END
ELSE
BEGIN
WHILE Again DO
BEGIN
IF DeskTop^.ExecView(Dialog) <> cmCancel
THEN
BEGIN
Dialog^.GetFileName (FullName);
Again := false; AppendToOldOutFile := false;
IF FullName<>'' THEN
BEGIN
{do this to trim length}
FSplit(FullName,Dir,Name,Ext);
FullName := Dir+Name+Ext;
IF FileExist(FullName) THEN
BEGIN
OutFD := PDialog(MyAppResFile.Get('OUTFILE_DB'));
IF ValidView(OutFD)<>nil THEN
BEGIN
todo := DeskTop^.ExecView(OutFD);
{cmYes: append, cmCancel: other name,
cmOk or cmNo: overwrite output file}
AppendToOldOutFile := (todo=cmYes);
Dispose(OutFD,Done);
END;
Again := (todo = cmCancel);
END; {IF bFileExist ...}
END; {IF FullName<>'' ...}
END {IF DeskTop^.ExecView(D)<>...}
ELSE
c := messagebox( 'You must choose an output file.', nil,
mfInformation+mfOkButton );
END; {WHILE Again DO ...}
Dispose(Dialog,Done);
END; {IF ValidView(D) ... ELSE ...}
IF FullName<>OutFileName THEN
BEGIN
IF OutFileOpen THEN
BEGIN close(outfile); OutFileOpen := false END;
OutFileName := FullName; FBox^.drawview;
END;
IF NOT OutFileOpen THEN
BEGIN
{open for append}
Assign ( outfile, OutFileName );
{$I-}
IF AppendToOldOutFile
THEN Append(outfile)
ELSE rewrite(outfile);
{$I+}
IF IOResult<>0 THEN
BEGIN donevideo; writeln ( 'Output file error'); halt END;
OutFileOpen := true;
END;
end; {OutFileDialog}
begin {RESDUMP}
IF Lo(DosVersion) >= 3
THEN EXEName := ParamStr(0)
ELSE
BEGIN
PrintStr ( 'Need DOS version > 3 !!'); halt
END;
FSplit(FExpand(EXEName),Ed,En,Ee);
BRSName := Ed+En+'.BRS';
RegisterDialogs;
RegisterObjects;
RegisterViews;
RegisterMenus;
RegisterType(RStringList);
RegisterType(RSortedListBox);
MyApp.Init;
MyApp.Run;
MyApp.Done;
end. {RESDUMP}